package com.qch.filter;


import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author qch
 * @Date 2021/2/19
 */
@Activate(group = {CommonConstants.CONSUMER_SIDE
})
public class TPMonitorFilter implements Filter {

    /**
     * String 服务名
     * Long 当前分钟对应的毫秒数
     * Long  耗时时间 Long 个数
     */
   // public static Map<String, Map<Long, TreeMap<Long, Long>>> TIME_RECORD = new ConcurrentHashMap<>();
    public static Map<String,List<TimeRecordDO>> TIME_RECORD_Map= new ConcurrentHashMap<>();

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        long startTime = System.currentTimeMillis();
        try {
            //执行方法
            return invoker.invoke(invocation);
        } finally {
            doCount(invocation,startTime);
        }
        //System.out.println("invoke time="+(System.currentTimeMillis()-startTime+"毫秒"));
    }


    private  void doCount(Invocation invocation,long startTime){
        String service = invocation.getServiceName();
        String methodName = invocation.getMethodName();
        String key = service + ":" + methodName;
        long endTime = System.currentTimeMillis();
        long spengtime = endTime - startTime;
        List<TimeRecordDO>list=new ArrayList<>();
        TimeRecordDO timeRecordDO=new TimeRecordDO(startTime,spengtime);
        if(TIME_RECORD_Map.containsKey(key))
        {
            list=TIME_RECORD_Map.get(key);
            list.add(timeRecordDO);
        }
        else {
            list.add(timeRecordDO);
            TIME_RECORD_Map.put(key,list);
        }

    }

    //忽视
    /*private synchronized void doCount1(Invocation invocation,long startTime){
          String service = invocation.getServiceName();
            String methodName = invocation.getMethodName();
            String key = service + ":" + methodName;
            long endTime = System.currentTimeMillis();
            long spengtime = endTime - startTime;

                //System.out.println("invoke time="+(spengtime+"毫秒"));
                Map<Long, TreeMap<Long, Long>> miniute_sc = new ConcurrentHashMap<>();
                //TreeMap: key为耗时,value为该耗时下的数据个数,TreeMap是红黑色树数据结构实现,可在初始化时指定其key的排序规则(从小到大):
                TreeMap<Long, Long> spendtime_count = new TreeMap<>(Comparator.naturalOrder());
                if (TIME_RECORD.containsKey(key)) {
                    miniute_sc = TIME_RECORD.get(key);
                    if (miniute_sc.size() > 0) {
                        if (miniute_sc.containsKey(getSecMillis(endTime))) {
                            spendtime_count = miniute_sc.get(getSecMillis(endTime));
                            if (spendtime_count.size() > 0) {
                                if (spendtime_count.containsKey(spengtime)) {
                                    Long cout = spendtime_count.get(spengtime) + 1;
                                    spendtime_count.put(spengtime, cout);
                                } else {
                                    spendtime_count.put(spengtime, 1L);
                                }
                            } else {
                                spendtime_count.put(spengtime, 1L);
                            }
                        } else {
                            spendtime_count.put(spengtime, 1L);
                        }
                        miniute_sc.put(getSecMillis(endTime), spendtime_count);
                    } else {
                        spendtime_count.put(spengtime, 1L);
                        miniute_sc.put(getSecMillis(endTime), spendtime_count);
                    }
                    TIME_RECORD.put(key, miniute_sc);
                } else {
                    spendtime_count.put(spengtime, 1L);
                    miniute_sc.put(getSecMillis(endTime), spendtime_count);
                    TIME_RECORD.put(key, miniute_sc);
                }



    }*/
    private long getSecMillis(long endTime) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTimeInMillis(endTime);
        // 将秒,毫秒域清零
        // cal1.set(Calendar.SECOND, 0);
        cal1.set(Calendar.MILLISECOND, 0);
        return cal1.getTimeInMillis();
    }
}
